package net.lainiao.dicom.common.storage;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.HashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class StorageLocalBatchUtils implements StorageBatchUtils {
    private static Logger logger = LoggerFactory.getLogger(StorageLocalBatchUtils.class);
    private String localPath;
    private int threadCount=5;
    public StorageLocalBatchUtils(String localPath) {
        this.localPath = localPath;
    }

    @Override
    public boolean getObjects(HashMap<String,String> hashMap) {
        LinkedBlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>();
        for (String val : hashMap.keySet()) {
            linkedBlockingQueue.add(val);
        }
        AtomicInteger errorCount = new AtomicInteger(0);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        for (int i = 0; i < threadCount; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    StorageLocalUtil storageLocalUtil = new StorageLocalUtil(localPath);
                    try {
                        storageLocalUtil.open();
                        String objectName = null;
                        while ((objectName = linkedBlockingQueue.poll()) != null) {
                            if(errorCount.get()>0){
                                break;
                            }
                            File targetFile = new File(hashMap.get(objectName));
                            int count=0;
                            while (count<3){
                                try {
                                    storageLocalUtil.getObject(objectName, targetFile);
                                    logger.debug("DownLoaded File:" + targetFile.getAbsolutePath());
                                    break;
                                }
                                catch (Exception e) {
                                    logger.warn("Download File Error ObjectName:"+objectName+" targetFile:"+targetFile.getAbsolutePath()+" Message:"+e.toString());
                                    count++;
                                }
                            }
                            if(count>=3){
                                throw new Exception("Download File Error ObjectName:"+objectName);
                            }
                        }
                    }
                    catch (Exception e) {
                        errorCount.incrementAndGet();
                        logger.error("DownLoad Files Error:" + e.toString());
                    }
                    finally {
                        storageLocalUtil.close();
                    }
                }
            });
        }
        executor.shutdown();
        try {
            while (!executor.awaitTermination(2, TimeUnit.SECONDS)) ;
        }
        catch (InterruptedException e) {

        }

        if (errorCount.get() > 0) {
            return false;
        }
        return true;
    }



    @Override
    public boolean putObjects(HashMap<String, File> hashMap) {
        LinkedBlockingQueue<String> linkedBlockingQueue = new LinkedBlockingQueue<>();
        for (String val : hashMap.keySet()) {
            linkedBlockingQueue.add(val);
        }
        AtomicInteger errorCount = new AtomicInteger(0);
        ThreadPoolExecutor executor = new ThreadPoolExecutor(threadCount, threadCount, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        for (int i = 0; i < 5; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    StorageLocalUtil storageLocalUtil = new StorageLocalUtil(localPath);
                    try {
                        storageLocalUtil.open();
                        String objectName = null;
                        while ((objectName = linkedBlockingQueue.poll()) != null) {
                            if(errorCount.get()>0){
                                break;
                            }
                            File targetFile = hashMap.get(objectName);
                            int count=0;
                            while (count<3){
                                try {
                                    storageLocalUtil.putObject(objectName, targetFile);
                                    logger.debug("Uploaded File:" + targetFile.getAbsolutePath());
                                    break;
                                }
                                catch (Exception e) {
                                    logger.warn("The Upload File  Error ObjectName:"+objectName+"File:" + targetFile.getAbsolutePath()+" Message:"+e.toString());
                                    count++;
                                }
                            }

                            if(count>=3){
                                throw new Exception("Upload File Error ObjectName:"+objectName+" File:"+targetFile.getAbsolutePath());
                            }
                        }
                    }
                    catch (Exception e) {
                        errorCount.incrementAndGet();
                        logger.error("Upload Files Error:" + e.toString());
                    }
                    finally {
                        storageLocalUtil.close();
                    }
                }
            });
        }
        executor.shutdown();
        try {
            while (!executor.awaitTermination(2, TimeUnit.SECONDS)) ;
        }
        catch (InterruptedException e) {

        }

        if (errorCount.get() > 0) {
            return false;
        }
        return true;
    }
}
